﻿Shader "Unlit/UnlitIce"
{
    Properties
    {
        [HDR]_Color ("Color", Color) = (1,1,1,1)
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
        [NoScaleOffset][Normal] _Normal("法线", 2D) = "bump" {}
        _NormalScale("法线强度", Float) = 1
        _Glossiness ("Smoothness", Range(0,1)) = 0.5
        _Metallic ("Metallic", Range(0,1)) = 0.0
        [Header(Refract)]
        [Space]
        _RefractRatio("折射强度", Range(0,1)) = 0.5
        [Header(Fresnel)]
        [Space]
        _FresnelPower("FresnelPower", Float) = 2
        _FresnelScale("FresnelScale", Float) = 1
        _FresnelBias("FresnelBias", Float) = 0
    }
    SubShader
    {
        Tags { "RenderType"="Transparent" "Queue"="Transparent"}
        LOD 100

        GrabPass{}
		zwrite off

        Pass
        {
            Blend SrcAlpha OneMinusSrcAlpha

            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
                half3 normal : NORMAL;
                half4 tangent : TANGENT;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                half4 tangent : TEXCOORD1;
                float3 normalWS : TEXCOORD2;
                half3 viewDir : TEXCOORD3;
                half3 worldPos : TEXCOORD4;
                float4 vertex : SV_POSITION;
            };

            sampler2D _MainTex;
            sampler2D _Normal;

            half _NormalScale;

            half _Glossiness;
            half _Metallic;
            fixed4 _Color;

            sampler2D _CameraDepthTexture;
		    sampler2D _GrabTexture;
		    half4 _GrabTexture_TexelSize;

            half _RefractRatio;

            half _FresnelPower;
            half _FresnelScale;
            half _FresnelBias;

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = v.uv;

                // 将法线从模型空间变换到世界空间
                half3 normalWS = UnityObjectToWorldNormal(v.normal);
                o.tangent = v.tangent;
                o.normalWS = normalWS;
                o.viewDir = normalize(WorldSpaceViewDir(v.vertex));
                o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;

                return o;
            }

            // 折射 i:入射光线方向 n:表面法线 eta:折射相对系数
            // I和N之间的角度太大则返回(0, 0, 0)
            float3 refract(float3 i, float3 n, float eta)
            {
                float cosi = dot(-i, n);
                float cost2 = 1 - eta * eta * (1 - cosi * cosi);
                float3 t = eta * i + n * (eta * cosi - sqrt(cost2));
                return t * step(0, cost2); // t * (int)(cost2 > 0)
            }

            half3x3 CreateTangentToWorldPerVertex(half3 normal, half3 tangent, half tangentSign)
            {
                // For odd-negative scale transforms we need to flip the sign
                half sign = tangentSign * unity_WorldTransformParams.w;
                half3 binormal = cross(normal, tangent) * sign;
                return half3x3(tangent, binormal, normal);
            }

            fixed4 frag (v2f IN) : SV_Target
            {
                IN.normalWS = normalize(IN.normalWS);
                IN.viewDir = normalize(IN.viewDir);

                float4 tangentWorld = float4(UnityObjectToWorldDir(IN.tangent.xyz), IN.tangent.w);
                float3x3 tangentToWorld = CreateTangentToWorldPerVertex(IN.normalWS, tangentWorld.xyz, tangentWorld.w);

                float3 tangentNormal = UnpackNormalWithScale(tex2D(_Normal, IN.uv), _NormalScale);
                float3 normalWorld = mul(tangentNormal, tangentToWorld);

                // 世界坐标观察方向   
                half3 viewDirection = normalize(_WorldSpaceCameraPos.xyz - IN.worldPos);

                // 折射
                half3 refraction = refract(-viewDirection, normalWorld, _RefractRatio);

                // 折射后的片段位置
                half3 refractionPositionWS = _WorldSpaceCameraPos.xyz + refraction;
                half4 refractionPositionCS = UnityWorldToClipPos(refractionPositionWS);
                half4 refractionUV = ComputeNonStereoScreenPos(refractionPositionCS);
                half4 SceneColor = tex2D(_GrabTexture, refractionUV.xy / refractionUV.w);

                fixed4 MainColor = tex2D(_MainTex, IN.uv) * _Color;

                // 菲涅耳
                half fresnel = saturate(_FresnelBias + _FresnelScale * pow(1.0f + dot(-viewDirection, normalWorld), _FresnelPower));
                SceneColor.rgb = lerp(SceneColor.rgb, MainColor.rgb, fresnel);

                SceneColor.a = _Color.a;

                return SceneColor;
            }
            ENDCG
        }
    }
}
